local CopyL = require("copy.CopyL")
local CopyDefine = require("copy.Define")
local ObjHuman = require("core.ObjHuman")
local ExcelMap = require("excel.Map")
local JZWarConfig = require("excel.JzWar")
local Timer = require("core.Timer")
local Map = require("core.Map")
local Msg = require("core.Msg")
local Obj = require("core.Obj")
local Lang = require("common.Lang")
local DailyActFL = require("activity.DailyActFL")
local ActDefine = require("activity.Define")
local MapScan = require("core.MapScan")
local BagLogic = require("bag.BagLogic")
local ItemDefine = require("bag.ItemDefine")
local Grid = require("bag.Grid")
local Util = require("common.Util")
local RoleHandler = require("role.HandlerL")
local ExcelLevelRewardConf = require("excel.LevelReward")
local Buffer = require("buffer.Buffer")
local Broadcast = require("broadcast.Broadcast")
local HtmlUtil = require("common.HtmlUtil")
local MailLogicFL = require("mail.MailLogicFL")
local SceneEvent = require("core.SceneEvent")
local Config = require("Config")
local CopyConfig = ExcelMap.copy
local JZWarBaseConfig = JZWarConfig.Base[1]
local JZWarRewardConfig = JZWarConfig.Reward[1]
local JZWarIncomeConfig = JZWarConfig.Income[1]

----------------------------
----------------------------
--V1 援军值 V2 威望 V3 积分
----------------------------
----------------------------

local NONE_SIDE = 0             --暂无分队
local RED_SIDE = 1              --红队
local BLUE_SIDE = 2             --蓝队

JZWAR_STATUS_LEAVED = -1        --离开战场
JZWAR_STATUS_NORMAL = 0         --正常状态
JZWAR_STATUS_DIE = 1            --已经死亡

PKData = PKData or {}
HumanWarDataList = HumanWarDataList or {}
SideHumanIDList = SideHumanIDList or {}
StatusList = StatusList or {}
RankList = RankList or {}
KillList = KillList or {}
HeartBeatCount = HeartBeatCount or {}
PowerRankList = PowerRankList or {}

function checkEnter(human)
    local nStartTime, nEndTime = getActTime()
    if nStartTime > 0 and nEndTime > 0 then
        if human.db.jzwarEnterTime >= nStartTime and human.db.jzwarEnterTime <= nEndTime then
            Broadcast.sendBroadcast(human, Lang.DOWN, Lang.JZWAR_ALD_ENTER)  --只能进一次
            return false
        end

        local nStartSplit =  os.time() - nStartTime
        if nStartSplit >= JZWarBaseConfig.beginfight then
            Broadcast.sendBroadcast(human, Lang.DOWN, Lang.JZWAR_STOP_ENTER)  --停止进入
            return false
        end
    else
        Broadcast.sendBroadcast(human, Lang.DOWN, Lang.JZWAR_NOT_START)  --活动暂未开启
        return false
    end
    return true
end

function onGetHumanSide(humanUuid)
    local nRoomID = CopyL.copyHuman2Room[humanUuid]
    if nRoomID and nRoomID > 0 and SideHumanIDList[nRoomID] then
        if SideHumanIDList[nRoomID][RED_SIDE][humanUuid] then
            return RED_SIDE
        elseif SideHumanIDList[nRoomID][BLUE_SIDE][humanUuid] then
            return BLUE_SIDE
        end
    end
    return NONE_SIDE
end

function onGetHumanStatus(humanUuid, roomID)
    return HumanWarDataList[roomID]._humanDataList[humanUuid] and HumanWarDataList[roomID]._humanDataList[humanUuid].status or JZWAR_STATUS_LEAVED
end

function onJZWarRoomBegin(copyID, roomID)
    HumanWarDataList[roomID] = {}
    HumanWarDataList[roomID]._roomData = {redScore = JZWarBaseConfig.redV1, blueScore = JZWarBaseConfig.blueV1}
    HumanWarDataList[roomID]._humanDataList = {}
    HumanWarDataList[roomID].static = -1    -- -1 备战状态 0 战斗状态 1 结束状态

    SideHumanIDList[roomID] = {}
    SideHumanIDList[roomID][RED_SIDE] = {}
    SideHumanIDList[roomID][BLUE_SIDE] = {}

    StatusList[roomID] = {}
    RankList[roomID] = {}
    PKData[roomID] = {curLen = JZWarBaseConfig.pkLen / 2, occupySide = 0}
    KillList[roomID] = {}
    PowerRankList[roomID] = {}

    HeartBeatCount[roomID] = 0
end

--得到开始时间
function getActTime()
    local nActData = getActData() 
    if not nActData or nActData.status ~= ActDefine.ACT_STATE_RUNNING then
        return 0, 0
    end
    return nActData.startTime, nActData.endTime
end

--得到活动剩余时间
function getLeftTime()
    local nActData = getActData()
    if not nActData or nActData.status ~= ActDefine.ACT_STATE_RUNNING then
        return 0
    end
    local t =  nActData.endTime - os.time()
    if t < 0 then t = 0 end
    return t
end

function getActData()
    return DailyActFL.onGetActData(ActDefine.ACT_TYPE_JZWAR_ACT)
end

function getPowerRank(human)
    if Config.IS_MIDDLE then
        return false
    end
    local nActData = getActData()
    if nActData and nActData.powerRank then
        for k, v in ipairs(nActData.powerRank) do
            if v.uuid == human._id then
                return k
            end
        end
    end
    return false 
end

function getMaxPowerRank()
    local nActData = getActData()
    if nActData and nActData.powerRank then
        return #nActData.powerRank
    end
    return 0
end

function getRankSide(rank)
    local nActData = getActData()
    if nActData and nActData.powerRank and nActData.powerRank[rank] then
        return nActData.powerRank[rank].side or false
    end
    return false 
end

function upDatePowerRank(rank, side)
    local nActData = getActData()
    if nActData and nActData.powerRank and nActData.powerRank[rank] then
        nActData.powerRank[rank].side = side 
        return true
    end
    return false
end

--开始副本
--function onJZWarHumanBeginCopy(human, copyID, roomID)
--
--end

function onJZWarHumanEndCopy(human, copyID, roomID)
    onHumanCtl(human, roomID, copyID)
end

function onInitSide(copyID, roomID)
    local nStep = 1
    local nFirstSide = nil
    local nSide = nil
    local nMapID = CopyConfig[copyID].mapList[2]
    if nMapID > 0 then
        for k, v in ipairs(PowerRankList[roomID]) do
            local nHuman = ObjHuman.onlineUuid[v[1]]
            --if nHuman and nHuman.fd then
            if nHuman then
                local nTempCopyID = CopyL.isCopyBySceneID(nHuman.scene_id)
                if nTempCopyID == copyID then
                    if nStep == 1 then
                        nFirstSide = onGetRondomSide()
                        nSide = nFirstSide
                        if nFirstSide > 0 then
                            SideHumanIDList[roomID][nFirstSide][nHuman._id] = nHuman
                        end
                    elseif nStep == 2 or nStep == 3 then
                        nSide = (nFirstSide == RED_SIDE and BLUE_SIDE or RED_SIDE)
                        SideHumanIDList[roomID][nSide][nHuman._id] = nHuman
                    elseif nStep == 4 then
                        nSide = nFirstSide
                        SideHumanIDList[roomID][nFirstSide][nHuman._id] = nHuman
                    end
                    if nSide == BLUE_SIDE then
                        ObjHuman.enterMap(nHuman, nMapID, JZWarBaseConfig.blueBornPos[1], JZWarBaseConfig.blueBornPos[2])
                    elseif nSide == RED_SIDE then
                        ObjHuman.enterMap(nHuman, nMapID, JZWarBaseConfig.redBornPos[1], JZWarBaseConfig.redBornPos[2])
                    end
                    if nStep % 4 == 0 then
                        nStep = 1
                    else
                        nStep = nStep + 1
                    end
                end
            end
        end
    end
end

--function onInitSide(copyID, roomID, human)
--    local nSide = NONE_SIDE
--    local nPowerRank = getPowerRank(human)
--    local nMaxPowerRank = getMaxPowerRank()
--    if nPowerRank ~= false and (nPowerRank % 2 == 0 or (nPowerRank % 2 ~= 0 and nPowerRank + 1 <= nMaxPowerRank)) then
--        local nCheckRank = (nPowerRank % 2 == 0) and (nPowerRank - 1) or (nPowerRank + 1)
--        local nCheckRankSide = getRankSide(nCheckRank)
--        if nCheckRankSide ~= false then
--            nSide = (nCheckRankSide == RED_SIDE) and BLUE_SIDE or RED_SIDE
--        end
--    end
--
--	if nSide == NONE_SIDE then
--		local nRedNum = 0
--		local nBlueNum = 0
--		local nRoomHumanList = CopyL.getCopyHumanList(copyID, roomID)
--		local nRoomHumanNum = #nRoomHumanList
--		for k, v in ipairs(nRoomHumanList) do
--			nSide = onGetHumanSide(v._id)
--			if nSide == RED_SIDE then
--				nRedNum = nRedNum + 1
--			elseif nSide == BLUE_SIDE then
--				nBlueNum = nBlueNum + 1
--			end
--		end
--		nSide = (nRedNum >= nBlueNum) and BLUE_SIDE or RED_SIDE
--	end
--    if nPowerRank ~= false and nSide ~= NONE_SIDE then
--        upDatePowerRank(nPowerRank, nSide)
--    end
--    return nSide
--
--    --if nRoomHumanNum < JZWarBaseConfig.initNum then
--    --    local nRedNum = 0
--    --    local nBlueNum = 0
--    --    for k, v in ipairs(nRoomHumanList) do
--    --        nSide = onGetHumanSide(v._id)
--    --        if nSide == RED_SIDE then
--    --            nRedNum = nRedNum + 1
--    --        elseif nSide == BLUE_SIDE then
--    --            nBlueNum = nBlueNum + 1
--    --        end
--    --    end
--    --    nSide = nRedNum >= nBlueNum and BLUE_SIDE or RED_SIDE
--    --elseif nRoomHumanNum >= JZWarBaseConfig.initNum then
--    --    local nRedZLSum = 0
--    --    local nBlueZLSum = 0
--    --    for k in pairs(HumanWarDataList[roomID]._humanDataList) do
--    --        local nHuman = ObjHuman.onlineUuid[k]
--    --        if nHuman then
--    --            if onGetHumanStatus(nHuman._id, roomID) ~= JZWAR_STATUS_LEAVED then
--    --                nSide = onGetHumanSide(nHuman._id)
--    --                if nSide == RED_SIDE then
--    --                    nRedZLSum = nRedZLSum + nHuman.db.zhandouli
--    --                elseif nSide == BLUE_SIDE then
--    --                    nBlueZLSum = nBlueZLSum + nHuman.db.zhandouli
--    --                end
--    --            end
--    --        end
--    --    end
--
--    --    if nRedZLSum <= nBlueZLSum then
--    --        nSide = RED_SIDE
--    --    else
--    --        nSide = BLUE_SIDE
--    --    end
--    --end
--
--    --return nSide
--end

function onJZWarHumanEnterCopy(human, copyID, roomID)
    local nSide = onGetHumanSide(human._id)
    if nSide == NONE_SIDE then
        if not HumanWarDataList[roomID]._humanDataList[human._id] and HumanWarDataList[roomID].static == -1 then
            HumanWarDataList[roomID]._humanDataList[human._id] = {v1 = 0, v2 = 0, v3 = 0, status = JZWAR_STATUS_NORMAL, beHitList = {}, bufAddCount = 0}
            onAddPowerList(roomID, human)
            human.enterCopyTime = Timer.now
            local nStartTime, nEndTime = getActTime()
            if nStartTime > 0 and nEndTime > 0 then
                local nStartSplit =  os.time() - nStartTime
                if nStartSplit < JZWarBaseConfig.beginfight then
                    local mm = Msg.gc.GC_SHOW_TXT
                    mm.txt = string.format("荆州争夺战将在%d秒后开始，请做好战斗准备！", JZWarBaseConfig.beginfight - nStartSplit)
                    Msg.send(mm, human.fd)
                end
            end
        else
            local backHomeMapId, backHomeX, backHomeY = CopyL.getBackHomePoint(human, copyID)
            ObjHuman.enterMap(human, backHomeMapId, backHomeX, backHomeY)
        end
    elseif HumanWarDataList[roomID].static == 0 then
        if nSide == BLUE_SIDE then
            human.camps = Obj.CAMPS_GOOD
        elseif nSide == RED_SIDE then
            human.camps = Obj.CAMPS_BAD
        end
        SideHumanIDList[roomID][nSide][human._id] = human
        HumanWarDataList[roomID]._humanDataList[human._id].status = JZWAR_STATUS_NORMAL
        human.enterCopyTime = Timer.now
    end
    onSendConfigData(human, copyID)
    
    human.db.jzwarEnterTime = os.time()

    --if not HumanWarDataList[roomID]._humanDataList[human._id] then
    --    HumanWarDataList[roomID]._humanDataList[human._id] = {v1 = 0, v2 = 0, v3 = 0, status = JZWAR_STATUS_NORMAL, beHitList = {}, bufAddCount = 0}
    --    local nSide = onInitSide(copyID, roomID, human)
    --    if nSide > 0 then
    --        SideHumanIDList[roomID][nSide][human._id] = human
    --        onJumpBackPos(human)
    --        human.enterCopyTime = Timer.now
    --    end
    --else
    --    local nSide = onGetHumanSide(human._id)
    --    if nSide == NONE_SIDE then
    --        nSide = onInitSide(copyID, roomID, human)
    --        SideHumanIDList[roomID][nSide][human._id] = human
    --        onJumpBackPos(human)
    --    else
    --        if nSide == BLUE_SIDE then
    --            human.camps = Obj.CAMPS_GOOD
    --        elseif nSide == RED_SIDE then
    --            human.camps = Obj.CAMPS_BAD
    --        end
    --    end
    --end
    --HumanWarDataList[roomID]._humanDataList[human._id].status = JZWAR_STATUS_NORMAL
    --human.enterCopyTime = Timer.now
    --onSendConfigData(human, copyID)
end

--function onJZWarHumanLeaveCopy(human, copyID, roomID, sceneID)
--end

local function get_grid(itemID, itemNum, itemColor)
    local grid = Grid.create(nil, itemID, itemNum, nil, ItemDefine.qualityOut[itemColor])
    return grid
end

function onSendConfigData(human, copyID)
    local nSendMsg = Msg.gc.GC_JZWAR_CONFIGDATA
    nSendMsg.pkLen = JZWarBaseConfig.pkLen
    nSendMsg.redLen = JZWarBaseConfig.redLen
    nSendMsg.blueLen = JZWarBaseConfig.blueLen
    nSendMsg.preLen = JZWarBaseConfig.pkDiff
    nSendMsg.killRankReward[0] = 0
    nSendMsg.centerRectList[0] = 0
    nSendMsg.blueForageRectList[0] = 0
    nSendMsg.redForageRectList[0] = 0
    nSendMsg.forageItemID = JZWarBaseConfig.forageItemID
    nSendMsg.side = onGetHumanSide(human._id)
    nSendMsg.backBloodPre = JZWarBaseConfig.backBloodPre
    nSendMsg.backBloodMoney = JZWarBaseConfig.backBloodMoney
    nSendMsg.beginfighttime = 0 

    local nStartTime, nEndTime = getActTime()
    if nStartTime > 0 and nEndTime > 0 then
        local nStartSplit =  os.time() - nStartTime
        if nStartSplit < JZWarBaseConfig.beginfight then
            nSendMsg.beginfighttime = JZWarBaseConfig.beginfight - nStartSplit
        end
    end

    --得到荆州杀敌排名奖励
    local nKillRankReward = JZWarRewardConfig.killRankReward
    for k, v in ipairs(nKillRankReward) do
        nSendMsg.killRankReward[0] = nSendMsg.killRankReward[0] + 1
        local nKillRankRewardMsgData = nSendMsg.killRankReward[nSendMsg.killRankReward[0]]
        nKillRankRewardMsgData.reward[0] = 0
        for kk, vv in ipairs(v) do
            nKillRankRewardMsgData.reward[0] = nKillRankRewardMsgData.reward[0] + 1
            local nRewarData = nKillRankRewardMsgData.reward[nKillRankRewardMsgData.reward[0]]
            local grid = get_grid(vv[1], vv[2], vv[3])
            Grid.makeItem(grid, nRewarData)
        end
    end

    --得到中心区域矩形列表
    local nCopyConfig = CopyConfig[copyID]
    local nMapID = nCopyConfig.mapList[2]
    if nMapID and nMapID > 0 then
        local nCenterAreaID = JZWarBaseConfig.centerAreaID
        for k, v in ipairs(nCenterAreaID) do
            local nListRect = Map.getRects(nMapID, v)
            for i = 1, #nListRect do
                nSendMsg.centerRectList[0] = nSendMsg.centerRectList[0] + 1
                local nRectMsgData = nSendMsg.centerRectList[nSendMsg.centerRectList[0]]
                local nRect = nListRect[i]
                nRectMsgData.leftTopPosX = nRect[1]
                nRectMsgData.leftTopPosY = nRect[2]
                nRectMsgData.rightBottomPosX = nRect[3]
                nRectMsgData.rightBottomPosY = nRect[4]
            end
        end

        local nRedForageAreaID = JZWarBaseConfig.redForageAreaID
        for k, v in ipairs(nRedForageAreaID) do
            local nListRect = Map.getRects(nMapID, v)
            for i = 1, #nListRect do
                nSendMsg.redForageRectList[0] = nSendMsg.redForageRectList[0] + 1
                local nRectMsgData = nSendMsg.redForageRectList[nSendMsg.redForageRectList[0]]
                local nRect = nListRect[i]
                nRectMsgData.leftTopPosX = nRect[1]
                nRectMsgData.leftTopPosY = nRect[2]
                nRectMsgData.rightBottomPosX = nRect[3]
                nRectMsgData.rightBottomPosY = nRect[4]
            end
        end

        local nBlueForageAreaID = JZWarBaseConfig.blueForageAreaID
        for k, v in ipairs(nBlueForageAreaID) do
            local nListRect = Map.getRects(nMapID, v)
            for i = 1, #nListRect do
                nSendMsg.blueForageRectList[0] = nSendMsg.blueForageRectList[0] + 1
                local nRectMsgData = nSendMsg.blueForageRectList[nSendMsg.blueForageRectList[0]]
                local nRect = nListRect[i]
                nRectMsgData.leftTopPosX = nRect[1]
                nRectMsgData.leftTopPosY = nRect[2]
                nRectMsgData.rightBottomPosX = nRect[3]
                nRectMsgData.rightBottomPosY = nRect[4]
            end
        end
    end

    Msg.send(nSendMsg, human.fd)
end

function onSendCopyData(copyID, roomID, sceneID)
    local nSendMsg = Msg.gc.GC_JZWAR_COPYDATA
    nSendMsg.occupySide = PKData[roomID].occupySide
    nSendMsg.redFlagNum = HumanWarDataList[roomID]._roomData.redScore
    nSendMsg.blueFlagNum = HumanWarDataList[roomID]._roomData.blueScore
    nSendMsg.leftTime = getLeftTime()
    nSendMsg.rankList[0] = 0
    for k, v in ipairs(RankList[roomID]) do
        nSendMsg.rankList[0] = nSendMsg.rankList[0] + 1
        local nRankMsgData = nSendMsg.rankList[nSendMsg.rankList[0]]
        if nRankMsgData then
            nRankMsgData.name = v[1]
            nRankMsgData.score = v[2]
            nRankMsgData.killnum = KillList[roomID][v[3]] and KillList[roomID][v[3]].killcount or 0
            nRankMsgData.side = v[4]
        end
        if k >= 3 then
            break
        end
    end
    nSendMsg.myScore = 0
    nSendMsg.myKillNum = 0
    nSendMsg.myWW = 0

    local nFds = Obj.scenes_fds[sceneID]
    if nFds then
        for k, v in pairs(nFds) do
            if v.obj_type == Obj.TYPE_HUMAN then
                nSendMsg.myScore = HumanWarDataList[roomID]._humanDataList[v._id] and HumanWarDataList[roomID]._humanDataList[v._id].v3 or 0
                nSendMsg.myKillNum = KillList[roomID][v._id] and KillList[roomID][v._id].killcount or 0
                nSendMsg.myWW = HumanWarDataList[roomID]._humanDataList[v._id] and HumanWarDataList[roomID]._humanDataList[v._id].v2 or 0
                Msg.send(nSendMsg, k)
                --Util.printTable(nSendMsg.rankList)
            end
        end
    end
end

function onSendPKData(diffNum, humanList)
    local nSendMsg = Msg.gc.GC_JZWAR_PKDATA
    nSendMsg.curLen = diffNum
    for k, v in pairs(humanList) do
        Msg.send(nSendMsg, v.fd)
    end
end

function onGetPKAreaData(mapID, copyID, roomID)
    local nCenterRedNum = 0
    local nCenterBlueNum = 0
    local nSceneID = CopyL.copyList[copyID][roomID][mapID]
    if not nSceneID or nSceneID <= 0 then
        return
    end
    local nSum, nHumanList = MapScan.scanAreaLiveHuman(mapID, nSceneID, JZWarBaseConfig.centerAreaID)
    if nSum > 0 then
        for nHumanUuid in pairs(nHumanList) do
            local nSide = onGetHumanSide(nHumanUuid)
            if nSide == BLUE_SIDE then
                nCenterBlueNum = nCenterBlueNum + 1
            elseif nSide == RED_SIDE then
                nCenterRedNum = nCenterRedNum + 1
            end
        end
    end
    return nCenterRedNum, nCenterBlueNum, nHumanList
end

function onPKCtl(nMapID, copyID, roomID)
    local nRedNum, nBlueNum, nHumanList = onGetPKAreaData(nMapID, copyID, roomID)
    local nDiffLen = math.ceil((nBlueNum - nRedNum) / JZWarBaseConfig.pkDiff)
    local nCurLen = PKData[roomID].curLen - nDiffLen
    if nCurLen < 0 then
        PKData[roomID].curLen = 0
    elseif nCurLen > JZWarBaseConfig.pkLen then
        PKData[roomID].curLen = JZWarBaseConfig.pkLen
    else
        PKData[roomID].curLen = nCurLen
    end
    local nOldOccupySide = PKData[roomID].occupySide
    if PKData[roomID].curLen >= (JZWarBaseConfig.pkLen - JZWarBaseConfig.redLen) then
        PKData[roomID].occupySide = RED_SIDE
    elseif PKData[roomID].curLen <= JZWarBaseConfig.blueLen then
        PKData[roomID].occupySide = BLUE_SIDE
    else
        PKData[roomID].occupySide = NONE_SIDE
    end
    return PKData[roomID].curLen, nHumanList, PKData[roomID].occupySide, nOldOccupySide
end

function onGetRondomSide()
    return (math.random(1, 100) % 2 == 0) and RED_SIDE or BLUE_SIDE
end

function onJZWarOneSec(copyID, roomID)
    HeartBeatCount[roomID] = HeartBeatCount[roomID] + 1

    -- 分配时间到
    local nStartTime, nEndTime = getActTime()
    if nStartTime > 0 and nEndTime > 0 then
        local nStartSplit =  os.time() - nStartTime
        if HumanWarDataList[roomID].static == -1 and nStartSplit >= JZWarBaseConfig.beginfight then
            table.sort(PowerRankList[roomID], powersort)
            onInitSide(copyID, roomID)
            HumanWarDataList[roomID].static = 0 
        end
    end

    local nCopyConfig = CopyConfig[copyID]
    local nMapID = nCopyConfig.mapList[1]

    if HumanWarDataList[roomID].static == 0 then
        nMapID = nCopyConfig.mapList[2]

        local nCurLen, nHumanList, nNowOccupySide, nOldOccupySide = onPKCtl(nMapID, copyID, roomID)
        local nSceneID = CopyL.copyList[copyID][roomID][nMapID]
        if nNowOccupySide == NONE_SIDE and nNowOccupySide ~= nOldOccupySide then
            if nOldOccupySide == RED_SIDE then
                SceneEvent.doSceneEvent(nSceneID, 108)
            elseif nOldOccupySide == BLUE_SIDE then
                SceneEvent.doSceneEvent(nSceneID, 106)
            end
            SceneEvent.doSceneEvent(nSceneID, 103)
        elseif nNowOccupySide ~= NONE_SIDE and nNowOccupySide ~= nOldOccupySide then
            local nContent1 = nil
            local nContent2 = nil
            if nOldOccupySide == NONE_SIDE then
                SceneEvent.doSceneEvent(nSceneID, 104)
            end

            if nNowOccupySide == RED_SIDE then
                nContent1 = Lang.JZWAR_PK_WINSIDE
                nContent2 = Lang.JZWAR_PK_REDSIDE_DEF
                SceneEvent.doSceneEvent(nSceneID, 106)
                SceneEvent.doSceneEvent(nSceneID, 107)
            elseif nNowOccupySide == BLUE_SIDE then
                nContent1 = Lang.JZWAR_PK_WINSIDE
                nContent2 = Lang.JZWAR_PK_BLUESIDE_DEF
                SceneEvent.doSceneEvent(nSceneID, 108)
                SceneEvent.doSceneEvent(nSceneID, 105)
            end
            onSendSideMsg(nNowOccupySide, nContent1, roomID)
            onSendSideMsg(nNowOccupySide == RED_SIDE and BLUE_SIDE or RED_SIDE, nContent2, roomID)
        end
        onSendPKData(nCurLen, nHumanList)

        --集体复活
        if HeartBeatCount[roomID] % JZWarBaseConfig.humanReliveTime == 0 then
            local humanList = CopyL.getCopyHumanList(copyID, roomID)
            for k, v in pairs(humanList) do
                if v.db.hp <= 0 then
                    RoleHandler.CG_REVIVE_GO_HOME(v, true)
                end
            end
        end

        if HeartBeatCount[roomID] % JZWarIncomeConfig.pkAddV1[2] == 0 then
            local nOccupySide = PKData[roomID].occupySide
            onAddV1(JZWarIncomeConfig.pkAddV1[1], nOccupySide, roomID)
        end

        local nFightAddV2Time = HeartBeatCount[roomID] % JZWarIncomeConfig.fightAddV2[2] == 0 and true or false
        local nFightAddExpTime = HeartBeatCount[roomID] % JZWarBaseConfig.fightAddExpTime == 0 and true or false

        if nFightAddV2Time or nFightAddExpTime then
            local nHumanList = CopyL.getCopyHumanList(copyID, roomID)
            for k, v in pairs(nHumanList) do
                for __, nAreaID in pairs(JZWarBaseConfig.bornAreaID) do
                    if not Map.is_in_area_id(v.db.map_id, v.db.x, v.db.y, nAreaID) then
                        if nFightAddV2Time then
                            onAddV2(JZWarIncomeConfig.fightAddV2[1], v)
                        end

                        if nFightAddExpTime then
                            ObjHuman.addExp(v, ExcelLevelRewardConf[8][v.db.lv].exp)
                        end
                    end
                end
            end
        end

        local nRemainTime = getLeftTime()
        if nRemainTime / 60 == 5 then
            onSendBroadcast(Lang.JZWAR_ENDBEFORE_5MIN, Lang.UP, copyID, roomID)
        end
    end

    --发送副本数据面板数据
    if HeartBeatCount[roomID] % 3 == 0 then
        local nSceneID = CopyL.copyList[copyID][roomID][nMapID]
        onSendCopyData(copyID, roomID, nSceneID)
    end
end

function onGetReviveTime(humanUuid)
    local nRoomID = CopyL.copyHuman2Room[humanUuid]
    if HeartBeatCount[nRoomID] then
        if HumanWarDataList[nRoomID].static == 1 then
            return 0
        else
            local nLeftTime = HeartBeatCount[nRoomID] % JZWarBaseConfig.humanReliveTime
            return JZWarBaseConfig.humanReliveTime - (nLeftTime == 0 and JZWarBaseConfig.humanReliveTime or nLeftTime)
        end
    end
end

function onJumpBackPos(human, isDead)
    local nRoomID = CopyL.copyHuman2Room[human._id]
    local nHumanWarData = HumanWarDataList[nRoomID]._humanDataList[human._id]
    if not nHumanWarData then
        return
    end
    local nSide = onGetHumanSide(human._id)
    if nSide and nSide ~= NONE_SIDE then
        if nSide == BLUE_SIDE then
            human.camps = Obj.CAMPS_GOOD
            Obj.jump(human, JZWarBaseConfig.blueBornPos[1], JZWarBaseConfig.blueBornPos[2], Msg.gc.GC_JUMP)
        elseif nSide == RED_SIDE then
            human.camps = Obj.CAMPS_BAD
            Obj.jump(human, JZWarBaseConfig.redBornPos[1], JZWarBaseConfig.redBornPos[2], Msg.gc.GC_JUMP)
        end
    end
    if isDead and nHumanWarData and nHumanWarData.bufAddCount < JZWarBaseConfig.dieAddBufCount then
        local nAddBufIDList = JZWarBaseConfig.dieAddBufID
        if nAddBufIDList then
            for k, v in pairs(nAddBufIDList) do
                Buffer.add(v, human, human)
            end
        end
        nHumanWarData.bufAddCount = nHumanWarData.bufAddCount + 1
    end
end

--boss死亡
function onJZWarMonsterDie(killer, monster, monsterID, copyID, roomID)
    local nHumanHurtList = monster.enemy_list
    if not nHumanHurtList then
        return
    end
    local nIsBossDie = false
    local nIsFlagDie = false
    local nBossDataTime = JZWarBaseConfig.bossData[monsterID]
    if nBossDataTime then
        if killer.obj_type == Obj.TYPE_HUMAN then
            nIsBossDie = true
        end
    end

    local nFlagDataTime = JZWarBaseConfig.flagData[monsterID]
    if nFlagDataTime then
        if killer.obj_type == Obj.TYPE_HUMAN then
            nIsFlagDie = true
        end
    end

    if nIsFlagDie or nIsBossDie then
        --计算所属方
        local nRedHurtSum = 0
        local nBlueHurtSum = 0
        local nBossHurtList = nil
        local nFlagHurtList = nil

        local nNow = os.time()
        for k, v in pairs(nHumanHurtList) do
            if nIsBossDie then
                if nNow - v.time <= nBossDataTime then
                    nBossHurtList = nBossHurtList or {}
                    nBossHurtList[k] = 1
                end
            elseif nIsFlagDie then
                if nNow - v.time <= nFlagDataTime then
                    nFlagHurtList = nFlagHurtList or {}
                    nFlagHurtList[k] = 1
                end
            end
            local nSide = onGetHumanSide(k)
            if nSide == BLUE_SIDE then
                nBlueHurtSum = nBlueHurtSum + v.hurt
            elseif nSide == RED_SIDE then
                nRedHurtSum = nRedHurtSum + v.hurt
            end
        end

        local nWinSide = (nBlueHurtSum > nRedHurtSum and BLUE_SIDE or RED_SIDE)
        local nFailSide = (nWinSide == BLUE_SIDE and RED_SIDE or BLUE_SIDE)

        -- 击杀了BOSS
        if nIsBossDie then
            local nAddBufIDList = JZWarBaseConfig.bossDieAddBufID[monsterID]
            if nAddBufIDList then
                for k, v in pairs(SideHumanIDList[roomID][nWinSide]) do
                    for kk, vv in pairs(nAddBufIDList) do
                        Buffer.add(vv, v, monster)
                    end
                end
            end

            -- 所属方增加援军值
            onAddV1(JZWarIncomeConfig.killBossWinAddV1, nWinSide, roomID)
            -- 非所属方增加援军值
            onAddV1(JZWarIncomeConfig.killBossFailAddV1, nFailSide, roomID)

            local nSideTemp = NONE_SIDE
            for k in pairs(nBossHurtList) do
                local nHuman = ObjHuman.onlineUuid[k]
                if nHuman then
                    nSideTemp = onGetHumanSide(nHuman._id)
                    if nSideTemp == nWinSide then
                        onAddV2(JZWarIncomeConfig.killBossWinAddV2, nHuman)
                        onAddV3(JZWarIncomeConfig.killBossWinAddV3, nHuman)
                    elseif nSideTemp == nFailSide then
                        onAddV2(JZWarIncomeConfig.killBossFailAddV2, nHuman)
                        onAddV3(JZWarIncomeConfig.killBossFailAddV3, nHuman)
                    end
                end
            end
        end

        -- 击杀了战旗
        if nIsFlagDie then
            -- 所属方增加援军值
            onAddV1(JZWarIncomeConfig.flagAddV1, nWinSide, roomID)

            for k in pairs(nFlagHurtList) do
                local nHuman = ObjHuman.onlineUuid[k]
                if nHuman then
                    onAddV2(JZWarIncomeConfig.flagAddV2, nHuman)
                    onAddV3(JZWarIncomeConfig.flagWinAddV3, nHuman)
                end
            end

            local nWinContent = nil
            local nFailContent = nil
            if nWinSide == RED_SIDE then
                nWinContent = Lang.JZWAR_REDSIDE_DESTORYFLAG
                nFailContent = Lang.JZWAR_BLUESIDE_BEDESTORYFLAG
            elseif nWinSide == BLUE_SIDE then
                nWinContent = Lang.JZWAR_BLUESIDE_DESTORYFLAG
                nFailContent = Lang.JZWAR_REDSIDE_BEDESTORYFLAG
            end
            onSendSideMsg(nWinSide, nWinContent, roomID)
            onSendSideMsg(nFailSide, nFailContent, roomID)
        end

    end
end

function onCheckComboKill()
    local nSendMsg = Msg.gc.GC_JZWAR_COMBOKILL
    for nRoomID, nRoomKillData  in pairs(KillList) do
        for nHumanUuid, nKillData in pairs(nRoomKillData) do
            if nKillData.change == true then
                nKillData.change = false
                nSendMsg.killNum = nKillData.comboKillCount
                local nHuman = ObjHuman.onlineUuid[nHumanUuid]
                if nHuman then
                    Msg.send(nSendMsg, nHuman.fd)
                end
            end
        end
    end
end

function onJZWarRoleBeHit(atker, human)
    local nRoomID = CopyL.copyHuman2Room[human._id]
    if nRoomID and nRoomID > 0 then
        local nBeHitData = HumanWarDataList[nRoomID]._humanDataList[human._id].beHitList
        nBeHitData[atker._id] = os.time()
    end
end

--人物死亡
function onJZWarRoleDieCB(atker, human, copyID, roomID)
    if atker.obj_type ~= Obj.TYPE_HUMAN then
        return
    end
    local nKillData = KillList[roomID][atker._id]
    if nKillData then
        local nKillDiffTime = os.time() - nKillData.comboKillTime
        if nKillDiffTime <= JZWarBaseConfig.comboKillTime then
            nKillData.comboKillCount = nKillData.comboKillCount + 1
        else
            nKillData.comboKillCount = 1
        end
        nKillData.killcount = nKillData.killcount + 1
        nKillData.noDieComboKillCount = nKillData.noDieComboKillCount + 1
        nKillData.comboKillTime = os.time()
        nKillData.killUuid = human._id
        nKillData.change = true
    else
        KillList[roomID][atker._id] = {comboKillTime = os.time(), killUuid = human._id, killcount = 1, comboKillCount = 1, noDieComboKillCount = 1, change = true}
        nKillData = KillList[roomID][atker._id]
    end
    --击杀增加积分
    local nKillSide = onGetHumanSide(atker._id)
    onAddV1(JZWarIncomeConfig.killHumanAddV1, nKillSide, roomID)
    onAddV3(JZWarIncomeConfig.killHumanAddV3, atker)

    --不死连杀增加积分
    local nNoDieComboKillCount = nKillData.noDieComboKillCount
    local nNoDieComboKillData = JZWarIncomeConfig.noDieComboKillAddV3[nNoDieComboKillCount]
    if nNoDieComboKillCount > 100 then
        if (nNoDieComboKillCount - 100) % JZWarBaseConfig.noDieComboKillMaxNum == 0 then
            nNoDieComboKillData = JZWarIncomeConfig.noDieComboKillAddV3[100]
            if nNoDieComboKillData then
                onAddV3(nNoDieComboKillData[1], atker)
            end
        end
    else
        if nNoDieComboKillData then
            onAddV3(nNoDieComboKillData[1], atker)
        end
    end

    --助攻结算
    for k, v in pairs(HumanWarDataList[roomID]._humanDataList[human._id].beHitList) do
        local nHuman = ObjHuman.onlineUuid[k]
        if nHuman and nHuman._id ~= atker._id then
            if os.time() - v <= JZWarBaseConfig.holdingTime then
                onAddV3(JZWarIncomeConfig.holdingKillAddV3, nHuman)
            end
        end
    end
    HumanWarDataList[roomID]._humanDataList[human._id].beHitList = {}


    local nAddBufIDList = JZWarBaseConfig.dieAddBufID
    if nAddBufIDList then
        for k, v in pairs(nAddBufIDList) do
            Buffer.removeID(v, atker)
        end
    end

    -- 击杀广播相关
    local nContent = nil
    local nBeKillSide = onGetHumanSide(human._id)
    if (nNoDieComboKillCount - 50) % JZWarBaseConfig.noDieComboKillMaxNum == 0 then
        nContent = JZWarIncomeConfig.noDieComboKillAddV3[100][2]
    else
        if nNoDieComboKillData then
            nContent = string.format(nNoDieComboKillData[2], HtmlUtil.font(atker.name, onGetSideHumanNameColor(nKillSide)), HtmlUtil.font(string.format(Lang.JZWAR_COMBOKILL, nNoDieComboKillCount), "#F1FF0A"))
            onSendBroadcast(nContent, Lang.UP, copyID, roomID)
        end
    end

    local nBeKillData = KillList[roomID][human._id]
    if nBeKillData and nBeKillData.noDieComboKillCount >= JZWarBaseConfig.breakNoDieComboKill then
        nContent = string.format(Lang.JZWAR_BREAK_COMBOKILL,
        HtmlUtil.font(atker.name, onGetSideHumanNameColor(nKillSide)),
        HtmlUtil.font(human.name, onGetSideHumanNameColor(nBeKillSide)),
        HtmlUtil.font(string.format(Lang.JZWAR_COMBOKILL, nBeKillData.noDieComboKillCount), "#F1FF0A"))
        nBeKillData.noDieComboKillCount = 0
        onSendBroadcast(nContent, Lang.UP, copyID, roomID)
    end

    --击杀前三名摄取积分
    for i = 1, 3 do
        local nRankData = RankList[roomID][i]
        if nRankData and nRankData[3] == human._id then
            local nDecV3 = math.ceil((HumanWarDataList[roomID]._humanDataList[human._id].v3 or 0) * (JZWarIncomeConfig.rankKillAddV3[i] / 100))
            onAddV3(-nDecV3, human)
            onAddV3(nDecV3, atker)
            break
        end
    end

    local nForageNum = BagLogic.getItemCount(human, JZWarBaseConfig.forageItemID)
    if nForageNum > 0 then
        local nTempNum = math.ceil(nForageNum * (JZWarBaseConfig.killForageDec / 100))
        BagLogic.delItemsById(human, JZWarBaseConfig.forageItemID, nTempNum, "jzwarforagedel")
        BagLogic.addItem(atker, JZWarBaseConfig.forageItemID, true, nTempNum, "jzwarforageadd")
        local nContent = string.format(Lang.JZWAR_KILL_DEC_FORAGE,
        HtmlUtil.font(atker.name, onGetSideHumanNameColor(nKillSide)),
        HtmlUtil.font(human.name, onGetSideHumanNameColor(nBeKillSide)), nTempNum)
        onSendBroadcast(nContent, Lang.GROSSIP, copyID, roomID)
    end
    if HeartBeatCount[roomID] % JZWarBaseConfig.humanReliveTime == 0 then
        RoleHandler.CG_REVIVE_GO_HOME(human, true)
    end
end

function onJZWarRoomFinish(copyID, roomID)
    local nRoomHumanList = CopyL.getCopyHumanList(copyID, roomID)
    for k, v in ipairs(nRoomHumanList) do
        local nHuman = ObjHuman.onlineUuid[v._id]
        if nHuman then
            --死亡的进行最后复活
            if nHuman.db.hp <= 0 then
                RoleHandler.CG_REVIVE_GO_HOME(nHuman, true)
            end
            onHumanCtl(nHuman, roomID, copyID)
        end
    end
end

-- 结算奖励
function onJZWarRoomClear(copyID, roomID)
    HumanWarDataList[roomID] = nil
    PKData[roomID] = nil
    KillList[roomID] = nil
    HeartBeatCount[roomID] = nil
    RankList[roomID] = nil
    SideHumanIDList[roomID] = nil
    HeartBeatCount[roomID] = nil
end

function onHumanCtl(human, roomID)
    local nSide = onGetHumanSide(human._id)
    if nSide ~= NONE_SIDE and roomID then
        --SideHumanIDList[roomID][nSide][human._id] = nil
        --HumanWarDataList[roomID]._humanDataList[human._id] = nil
        HumanWarDataList[roomID]._humanDataList[human._id].status = JZWAR_STATUS_LEAVED
    end

    local nAddBufIDList = JZWarBaseConfig.dieAddBufID
    if nAddBufIDList then
        for k, v in pairs(nAddBufIDList) do
            Buffer.removeID(v, human)
        end
    end

    for k, v in pairs(JZWarBaseConfig.bossDieAddBufID) do
        Buffer.removeID(v[1], human)
    end

    local nForageNum = BagLogic.getItemCount(human, JZWarBaseConfig.forageItemID)
    if nForageNum > 0 then
        BagLogic.delItemsById(human, JZWarBaseConfig.forageItemID, nForageNum, "jzwarforagedel")
    end

    human.camp = Obj.CAMPS_NONE
end

function onJZWarRoomEnd()
    for nRoomID in pairs(HumanWarDataList) do
        if HumanWarDataList[nRoomID] and HumanWarDataList[nRoomID].static == 1 then
            break
        end
        HumanWarDataList[nRoomID].static = 1
        local nJZWarRoomData = HumanWarDataList[nRoomID]
        if nJZWarRoomData then
            local nWinSide = NONE_SIDE
            if nJZWarRoomData._roomData.redScore > nJZWarRoomData._roomData.blueScore then
                nWinSide = RED_SIDE
            elseif nJZWarRoomData._roomData.redScore < nJZWarRoomData._roomData.blueScore then
                nWinSide = BLUE_SIDE
            end

            if nWinSide ~= NONE_SIDE then
                local nFailSide = (nWinSide == BLUE_SIDE and RED_SIDE or BLUE_SIDE)
                local nWinRewardList = {}
                for k, v in ipairs(JZWarRewardConfig.winReward) do
                    nWinRewardList[#nWinRewardList + 1] = get_grid(v[1], v[2], v[3])
                end

                local nFailRewardList = {}
                for k, v in ipairs(JZWarRewardConfig.failReward) do
                    nFailRewardList[#nFailRewardList + 1] = get_grid(v[1], v[2], v[3])
                end

                for k in pairs(SideHumanIDList[nRoomID][nWinSide]) do
                    local nHuman = ObjHuman.onlineUuid[k]
                    if nHuman then
                        onAddV3(JZWarIncomeConfig.endWinAddV3, nHuman)
                    end
                    MailLogicFL.CreateNewMailForUser(k, Lang.JZWAR_MAIL_TITLE, Lang.JZWAR_WINSIDE_MAIL, nWinRewardList)
                end

                for k in pairs(SideHumanIDList[nRoomID][nFailSide]) do
                    MailLogicFL.CreateNewMailForUser(k, Lang.JZWAR_MAIL_TITLE, Lang.JZWAR_FAILSIDE_MAIL, nFailRewardList)
                end
            else
                local nDrawRewardList = {}
                for k, v in ipairs(JZWarRewardConfig.drawReward) do
                    nDrawRewardList[#nDrawRewardList + 1] = get_grid(v[1], v[2], v[3])
                end
                for k in pairs(SideHumanIDList[nRoomID][BLUE_SIDE]) do
                    local nHuman = ObjHuman.onlineUuid[k]
                    if nHuman then
                        onAddV3(JZWarIncomeConfig.endWinAddV3, nHuman)
                    end
                    MailLogicFL.CreateNewMailForUser(k, Lang.JZWAR_MAIL_TITLE, Lang.JZWAR_DRAWGAME_MAIL, nDrawRewardList)
                end
                for k in pairs(SideHumanIDList[nRoomID][RED_SIDE]) do
                    local nHuman = ObjHuman.onlineUuid[k]
                    if nHuman then
                        onAddV3(JZWarIncomeConfig.endWinAddV3, nHuman)
                    end
                    MailLogicFL.CreateNewMailForUser(k, Lang.JZWAR_MAIL_TITLE, Lang.JZWAR_DRAWGAME_MAIL, nDrawRewardList)
                end
            end

            local nCopyConfig = CopyConfig[CopyDefine.COPY_JZWAR_ID]
            if nCopyConfig then
                local nMapID = nCopyConfig.mapList[2]
                local nSceneID = CopyL.copyList[CopyDefine.COPY_JZWAR_ID][nRoomID][nMapID]
                if nSceneID then
                    onSendCopyData(CopyDefine.COPY_JZWAR_ID, nRoomID, nSceneID)
                end
            end

            local nRankRewardList = nil
            for i = 1, 3 do
                nRankRewardList = {}
                if JZWarRewardConfig.killRankReward[i] then
                    for k, v in ipairs(JZWarRewardConfig.killRankReward[i]) do
                        nRankRewardList[#nRankRewardList + 1] = get_grid(v[1], v[2], v[3])
                    end

                    local nRankData = RankList[nRoomID][i]
                    if nRankData then
                        MailLogicFL.CreateNewMailForUser(nRankData[3], Lang.JZWAR_MAIL_TITLE, Lang.JZWAR_RANK_MAIL, nRankRewardList)
                    end
                end
            end
        end


        CopyL.roomFinish(CopyDefine.COPY_JZWAR_ID, nRoomID, CopyDefine.COPY_FINISH_ACT_END, "活动结束")
    end
end

-- 增加援军值
function onAddV1(v1, side, roomID)
    if side == RED_SIDE then
        HumanWarDataList[roomID]._roomData.redScore = HumanWarDataList[roomID]._roomData.redScore + v1
    elseif side == BLUE_SIDE then
        HumanWarDataList[roomID]._roomData.blueScore = HumanWarDataList[roomID]._roomData.blueScore + v1
    end
end

-- 增加威望
function onAddV2(v2, human)
    local nRoomID = CopyL.copyHuman2Room[human._id]
    local nHumanWarData = HumanWarDataList[nRoomID]._humanDataList[human._id]
    if nRoomID and nRoomID > 0 and nHumanWarData and nHumanWarData.status ~= JZWAR_STATUS_LEAVED then
        nHumanWarData.v2 = nHumanWarData.v2 + v2
        ObjHuman.addPrestige(human, v2, "jingzhou_copy")
    end
end

-- 增加积分
function onAddV3(v3, human)
    local nHumanUuid = human._id
    local nRoomID = CopyL.copyHuman2Room[nHumanUuid]
    if HumanWarDataList[nRoomID] then
        local nHumanWarData = HumanWarDataList[nRoomID]._humanDataList[human._id]
        if nRoomID and nRoomID > 0 and nHumanWarData and nHumanWarData.status ~= JZWAR_STATUS_LEAVED then
            local nV3Src = nHumanWarData.v3
            local nV3Temp = nHumanWarData.v3 + v3
            nHumanWarData.v3 = nV3Temp < 0 and 0 or nV3Temp
            if v3 > 0 or (v3 < 0 and nV3Src > 0) then
                onV3Rank(human, v3, nRoomID)
            end
        end
    end
end

function onForage(human)
    local nHumanUuid = human._id
    local nCopyID = CopyL.mapID2CopyID[human.db.map_id]
    if not nCopyID or nCopyID <= 0 then
        return
    end
    local nRoomID = CopyL.copyHuman2Room[human._id]
    local nHumanWarData = HumanWarDataList[nRoomID]._humanDataList[nHumanUuid]
    if nHumanWarData and nHumanWarData.status == JZWAR_STATUS_NORMAL then
        local msgErr = Msg.gc.GC_BROADCAST
        msgErr.type = Lang.MOUSE
        local nForageNum = BagLogic.getItemCount(human, JZWarBaseConfig.forageItemID)
        if nForageNum > 0 then
            local nIsInSideArea = false
            local nSide = onGetHumanSide(human._id)
            if nSide == RED_SIDE then
                for k, v in pairs(JZWarBaseConfig.redForageAreaID) do
                    if Map.is_in_area_id(human.db.map_id, human.db.x, human.db.y, v) then
                        nIsInSideArea = true
                        break
                    end
                end
            elseif nSide == BLUE_SIDE then
                for k, v in pairs(JZWarBaseConfig.blueForageAreaID) do
                    if Map.is_in_area_id(human.db.map_id, human.db.x, human.db.y, v) then
                        nIsInSideArea = true
                        break
                    end
                end
            end
            if nIsInSideArea then
                onAddV1(JZWarIncomeConfig.forageAddV1 * nForageNum, nSide, nRoomID)
                onAddV2(JZWarIncomeConfig.forageAddV2 * nForageNum, human)
                onAddV3(JZWarIncomeConfig.forageAddV3 * nForageNum, human)
            else
                msgErr.msg = "请到所属方递交粮草!"
                Msg.send(msgErr, human.fd)
                return
            end
            BagLogic.delItemsById(human, JZWarBaseConfig.forageItemID, nForageNum, "jzwarforagedel")
            msgErr.msg = string.format("成功交粮草!获得%d积分", JZWarIncomeConfig.forageAddV3 * nForageNum)
            Msg.send(msgErr, human.fd)
        else
            msgErr.msg = "您身上缺少荆州粮草!"
            Msg.send(msgErr, human.fd)
        end
    end
end

function onBackBlood(human, moneyNum)
    local nHumanUuid = human._id
    local nCopyID = CopyL.mapID2CopyID[human.db.map_id]
    local nCurHp = ObjHuman.getHp(human)
    if not nCopyID or nCopyID <= 0 or nCurHp <= 0 then
        return
    end
    local nRoomID = CopyL.copyHuman2Room[human._id]
    local nHumanWarData = HumanWarDataList[nRoomID]._humanDataList[nHumanUuid]
    if nHumanWarData and nHumanWarData.status == JZWAR_STATUS_NORMAL then
        local msgErr = Msg.gc.GC_BROADCAST
        msgErr.type = Lang.MOUSE
        local nBackBloodNum = ObjHuman.getHpMax(human) - nCurHp 
        if nBackBloodNum == 0 then
            msgErr.msg = "血量已满!"
            Msg.send(msgErr, human.fd)
            return
        end
        local nHumanMoney = ObjHuman.getYinliang(human)
        if nHumanMoney < JZWarBaseConfig.backBloodMoney then
            msgErr.msg = "银两不足!"
            Msg.send(msgErr, human.fd)
            return
        end
        local nNeedMoney = JZWarBaseConfig.backBloodMoney * (math.ceil(nBackBloodNum / JZWarBaseConfig.backBloodPre))
        local nRealMoney = (nNeedMoney <= nHumanMoney) and nNeedMoney or nHumanMoney 
        if nRealMoney > 0 then
            local nIsInSideArea = false
            local nSide = onGetHumanSide(human._id)
            if nSide == RED_SIDE then
                for k, v in pairs(JZWarBaseConfig.redForageAreaID) do
                    if Map.is_in_area_id(human.db.map_id, human.db.x, human.db.y, v) then
                        nIsInSideArea = true
                        break
                    end
                end
            elseif nSide == BLUE_SIDE then
                for k, v in pairs(JZWarBaseConfig.blueForageAreaID) do
                    if Map.is_in_area_id(human.db.map_id, human.db.x, human.db.y, v) then
                        nIsInSideArea = true
                        break
                    end
                end
            end
            if not nIsInSideArea then
                msgErr.msg = "请到所属方递交粮草!"
                Msg.send(msgErr, human.fd)
                return
            end
            ObjHuman.decYinliang(human, nRealMoney, "jzwarbackblood")
            local nAddHp = nRealMoney * JZWarBaseConfig.backBloodPre
            ObjHuman.setHp(human, nCurHp + nAddHp) 
            msgErr.msg = string.format("成功回血%d!消耗%d银两", nAddHp, nRealMoney)
            Msg.send(msgErr, human.fd)
        else
            msgErr.msg = "银两不足!"
            Msg.send(msgErr, human.fd)
        end
    end

end

function onCollectDieCB(human, collect, collect_id)
    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE

    local nForageConfigData = JZWarBaseConfig.forageItemData[collect_id]
    if nForageConfigData then
        local nItemID = nForageConfigData[1]
        local nItemNum = nForageConfigData[2]
        local nCanAdd = BagLogic.checkCanAddItem(human, nItemID, true, nItemNum)
        if not nCanAdd then
            msgErr.msg = "背包空间不足"
            Msg.send(msgErr, human.fd)
            return
        end

        if ItemDefine.isEquip(nItemID) then
            local nGridData = Grid.create(nil, nItemID,  true)
            BagLogic.addItemByGrid(human, nil, nGridData, "jzwarforageadd")
        else
            BagLogic.addItem(human, nItemID, true, nItemNum, "jzwarforageadd")
        end
    end
end

function onV3Rank(human, score, roomID)
    local nHumanUuid = human._id
    local nSceneID = human.scene_id
    local nScoreRankData = RankList[roomID]
    if not nSceneID or nSceneID <= 0 or not RankList or not nScoreRankData then
        return
    end

    local nScore = HumanWarDataList[roomID]._humanDataList[nHumanUuid].v3

    local nBeforeRank = 0
    local nCurRank = 0

    if #nScoreRankData == 0 then
        onAddRankList(nScoreRankData, 1, human, nScore)
    else
        for k, v in ipairs(nScoreRankData) do
            if v[3] == nHumanUuid then
                nBeforeRank = k
                break
            end
        end

        if nBeforeRank == 1 and (nScore >= nScoreRankData[1][2] or #nScoreRankData == 1) then
            nScoreRankData[1][2] = nScore
            nCurRank = 1
        elseif nBeforeRank > 0 and (nScoreRankData[nBeforeRank -1] and nScore <= nScoreRankData[nBeforeRank - 1][2]) and ((nScoreRankData[nBeforeRank + 1] 
            and nScore >= nScoreRankData[nBeforeRank + 1][2]) or nBeforeRank == #nScoreRankData) then
            nScoreRankData[nBeforeRank][2] = nScore
            nCurRank = nBeforeRank
        else
            if nBeforeRank > 0 then
                table.remove(nScoreRankData, nBeforeRank)
            end
            for k = #nScoreRankData, 1, -1 do
                if nScoreRankData[k] then
                    if k == 1 then
                        if nScore < nScoreRankData[k][2] then
                            onAddRankList(nScoreRankData, k + 1, human, nScore)
                            nCurRank = k + 1
                            break
                        else
                            onAddRankList(nScoreRankData, 1, human, nScore)
                            nCurRank = 1
                            break
                        end
                    else
                        if nScore <= nScoreRankData[k][2] then
                            onAddRankList(nScoreRankData, k + 1, human, nScore)
                            nCurRank = k + 1
                            break
                        end
                    end
                end
            end

        end
    end
end

--function onV3RankOld(human, score, roomID)
--    local nHumanUuid = human._id
--    local nSceneID = human.scene_id
--    local nScoreRankData = RankList[roomID]
--    if not nSceneID or nSceneID <= 0 or not RankList or not nScoreRankData then
--        return
--    end
--
--    local nScore = HumanWarDataList[roomID]._humanDataList[nHumanUuid].v3
--
--    local nBeforeRank = 0
--    local nCurRank = 0
--
--    --local nRankMax = 3
--    --if nScore > 0 and (#nScoreRankData < nRankMax or nScore >= nScoreRankData[nRankMax][2]) then
--    if #nScoreRankData == 0 then
--        onAddRankList(nScoreRankData, 1, human, nScore)
--    else
--        for k, v in ipairs(nScoreRankData) do
--            if v[3] == nHumanUuid then
--                nBeforeRank = k
--                break
--            end
--        end
--
--        if nBeforeRank == 1 and nScore >= nScoreRankData[1][2] then
--            nScoreRankData[1][2] = nScore
--            nCurRank = 1
--        else
--            local nBegin = 0
--            local nLast = 0
--            if nBeforeRank == 0 then
--                nBegin = 1
--                nLast = #nScoreRankData 
--            else
--                if nBeforeRank > 0 and (nScoreRankData[nBeforeRank -1] and nScore <= nScoreRankData[nBeforeRank - 1][2]) and ((nScoreRankData[nBeforeRank + 1] 
--                    and nScore >= nScoreRankData[nBeforeRank + 1][2]) or nBeforeRank <= #nScoreRankData) then
--                    nScoreRankData[nBeforeRank][2] = nScore
--                    nCurRank = nBeforeRank
--                    nLast = nBegin- 1
--                else
--                    if nBeforeRank > 0 and (nScoreRankData[nBeforeRank - 1] and nScore > nScoreRankData[nBeforeRank - 1][2]) then
--                        nBegin = 1
--                        nLast = nBeforeRank - 1
--                    elseif nBeforeRank > 0 and (nScoreRankData[nBeforeRank + 1] and nScore < nScoreRankData[nBeforeRank + 1][2]) then
--                        nBegin = nBeforeRank
--                        nLast = #nScoreRankData 
--                    end
--                    table.remove(nScoreRankData, nBeforeRank)
--                end
--            end
--
--            print(nBeforeRank)
--            print(nScore)
--            print(nBegin)
--            print(nLast)
--            if nLast == nBegin then
--                if nScore == nScoreRankData[nLast][2] then
--                    onAddRankList(nScoreRankData, nBegin + 1, human, nScore)
--                else
--                    onAddRankList(nScoreRankData, nBegin, human, nScore)
--                end
--            elseif nLast > nBegin then
--                for k = nLast, nBegin, -1 do
--                    if nScoreRankData[k] then
--                        if k == 1 then
--                            if nScore < nScoreRankData[k][2] then
--                                onAddRankList(nScoreRankData, k + 1, human, nScore)
--                                nCurRank = k + 1
--                                break
--                            else
--                                onAddRankList(nScoreRankData, 1, human, nScore)
--                                nCurRank = 1
--                                break
--                            end
--                        else
--                            if nScore <= nScoreRankData[k][2] then
--                                onAddRankList(nScoreRankData, k + 1, human, nScore)
--                                nCurRank = k + 1
--                                break
--                            end
--                        end
--                    end
--                end
--            end
--        end
--    end
--end

function onAddRankList(killRankData, rank, human, score)
    local nSide = onGetHumanSide(human._id) 
    if nSide ~= NONE_SIDE then
        table.insert(killRankData, rank, {human.name, score, human._id, nSide})
    end
end

function onGetSideHumanNameColor(side)
    if side == RED_SIDE then
        return "#FF0000"
    elseif side == BLUE_SIDE then
        return "#00B0F0"
    end
end

function onSendBroadcast(content, type, copyID, roomID)
    local nMsg = Msg.gc.GC_BROADCAST
    nMsg.type = type
    nMsg.msg = content
    CopyL.sendCopy(nMsg, copyID, roomID)
end

function onSendSideMsg(side, content, roomID)
    local nFds = onGetSideFds(side, roomID)
    if nFds[0] > 0 then
        Broadcast.sendBroadcastFDs(nFds, Lang.UP, content)
    end
end

function onGetSideFds(side, roomID)
    local nFds = {}
    local nLen = 0
    for k in pairs(SideHumanIDList[roomID][side]) do
        local nHuman = ObjHuman.onlineUuid[k]
        if nHuman and nHuman.fd then
            nLen = nLen + 1
            nFds[nLen] = nHuman.fd
        end
    end
    nFds[0] = nLen
    return nFds
end

function onAddPowerList(roomid, human)
    table.insert(PowerRankList[roomid], {human._id, human.db.zhandouli, human.name})
end

function powersort(a, b)
    return (a[2] > b[2]) and true or false
end

DailyActFL.onRegisterCallBack(ActDefine.ACT_TYPE_JZWAR_ACT, nil, nil, onJZWarRoomEnd)
